package com.itlong.cloud.controller.robot;

import com.itlong.cloud.POJO.PO.AppRobotOperateLogPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.robot.AppRobotAccountInfoGetVO;
import com.itlong.cloud.POJO.VO.app.robot.AppRobotLoginCacheVO;
import com.itlong.cloud.POJO.VO.app.robot.AppRobotProjectInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.SystemTypeEnum;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.noncore.commons.IRobotLoginLogServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppRobotLoginServiceClient;
import com.itlong.cloud.user.app.IAppUserInfoCacheServiceClient;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.Md5;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.random.LogicIdUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 *     机器人APP登录控制器
 * </desc>
 *
 * @create  2018/10/15
 */
@RestController
@RequestMapping("/robot")
@RefreshScope
public class AppRobotLoginController extends BaseController {

    @Autowired
    private RedisService<AppRobotLoginCacheVO> redisService;

    @Autowired
    private IAppRobotLoginServiceClient iAppRobotLoginServiceClient;

    @Autowired
    private IAppUserInfoCacheServiceClient iAppUserInfoCacheServiceClient;

    @Autowired
    private IRobotLoginLogServiceClient iRobotLoginLogServiceClient;

    @Value("${" + PlatformConstants.APP_USER_TOKEN_KEY + "}")
    private String APP_USER_TOKEN_KEY;

    /**
     * <desc>
     *      机器人APP登录
     * </desc>
     *
     * @param account 账号
     * @param password 密码
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/10/15
     */
    @ResponseBody
    @PostMapping("login")
    @LoggerInfo(operateDesc = "robotLogin")
    public MessageVO robotLogin(String account, String password, String robotUnique, HttpServletRequest request){
        try {
            password = UserTokenUtil.getPassword(password,APP_USER_TOKEN_KEY);
            if (StringUtils.isBlank(robotUnique)) {
                return new MessageVO(AppErrorCodeEnum.ROBOT_UNIQUE_EMPTY_ERR.getErrorCode());
            }
            if (password == null) {
                password = "";
            }
            password = Md5.En(password);
            if (account == null) {
                account = "";
            }
            AppRobotAccountInfoGetVO appRobotAccountInfoGetVO = iAppRobotLoginServiceClient.getRobotUserByAccount(account);
            if (appRobotAccountInfoGetVO == null) {
                return new MessageVO(AppErrorCodeEnum.ACCOUNT_NOT_EXIST_ERR.getErrorCode());
            }
            if (appRobotAccountInfoGetVO.getUseStatus() == 2) {
                return new MessageVO(AppErrorCodeEnum.ACCOUNT_FORBIDDEN_ERR.getErrorCode());
            }
            if (DataStatusEnum.BAN.getType().equals(appRobotAccountInfoGetVO.getStatus())) {
                return new MessageVO(AppErrorCodeEnum.ACCOUNT_FORBIDDEN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(appRobotAccountInfoGetVO.getProjectId())){
                return new MessageVO(AppErrorCodeEnum.USER_NOT_PROJECT.getErrorCode());
            }
            String abateTime = appRobotAccountInfoGetVO.getAbateTime();
            Date abateTimeDate = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).parse(abateTime);
            Date operateTimeDate = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).parse(appRobotAccountInfoGetVO.getOperationTime());
            Date nowTime = new Date();
            if (abateTimeDate.compareTo(nowTime) <= 0) {
                return new MessageVO(AppErrorCodeEnum.ACCOUNT_OUT_OF_DATE_ERR.getErrorCode());
            }
            if (operateTimeDate.compareTo(nowTime) > 0) {
                return new MessageVO(AppErrorCodeEnum.ACCOUNT_NOT_TO_DATE_ERR.getErrorCode());
            }
            if (!password.equals(appRobotAccountInfoGetVO.getPassword())) {
                return new MessageVO(AppErrorCodeEnum.PASSWORD_ERR.getErrorCode());
            }
            // 到这里登录成功，保存用户信息到缓存
            String token = UserTokenUtil.tokenEncrypt(appRobotAccountInfoGetVO.getAppRobotAccountId(),APP_USER_TOKEN_KEY,SystemTypeEnum.ROBOT.getType());
            String cacheKey = String.format("%s%s", RedisConstant.ROBOT_USER_REDIS_KEY, appRobotAccountInfoGetVO.getAppRobotAccountId());
            AppRobotLoginCacheVO appRobotLoginCacheVO = iAppUserInfoCacheServiceClient.getRobotLoginCache(token);
            if (appRobotLoginCacheVO == null) {
                appRobotLoginCacheVO = new AppRobotLoginCacheVO();
            }
            // 属性复制每次都做，保证缓存中数据及时更新
            BeanUtils.copyProperties(appRobotAccountInfoGetVO,appRobotLoginCacheVO);
            // 判断已同时登录的个数
            List<String> robotUniques = appRobotLoginCacheVO.getRobotUniques();
            if (robotUniques != null) {
                if (!robotUniques.contains(robotUnique) && robotUniques.size() >= appRobotAccountInfoGetVO.getLoginCount()) {
                    return new MessageVO(AppErrorCodeEnum.ROBOT_LOGIN_COUNT_ERR.getErrorCode());
                }
                if (!robotUniques.contains(robotUnique) && robotUniques.size() < appRobotAccountInfoGetVO.getLoginCount()) {
                    robotUniques.add(robotUnique);
                }
            } else {
                robotUniques = new ArrayList<>();
                robotUniques.add(robotUnique);
            }
            appRobotLoginCacheVO.setDeveloperUserId(appRobotAccountInfoGetVO.getAppId());
            appRobotLoginCacheVO.setAppSecret(appRobotAccountInfoGetVO.getAppSecret());
            appRobotLoginCacheVO.setRobotUniques(robotUniques);
            appRobotLoginCacheVO.setToken(token);
            redisService.set(cacheKey,RedisConstant.REDIS_ROBOT_USER_CACHE_TIME,appRobotLoginCacheVO);
            request.setAttribute("appRobotAccountId",appRobotAccountInfoGetVO.getAppRobotAccountId());
            // 返回数据
            Map<String,String> data = new HashMap<>();
            data.put("token",token);
            data.put("type",appRobotAccountInfoGetVO.getUseStatus().toString());
            data.put("robotProjectName",appRobotAccountInfoGetVO.getRobotProjectName());
            data.put("robotId",appRobotAccountInfoGetVO.getRobotId());
            data.put("appSecret",appRobotAccountInfoGetVO.getAppSecret());
            data.put("projectId",appRobotAccountInfoGetVO.getProjectId());
            data.put("projectName",appRobotAccountInfoGetVO.getCurrentProjectName());
            data.put("appId",appRobotAccountInfoGetVO.getAppId());
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1);
            data.put("statTime",sdf.format(new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).parse(appRobotAccountInfoGetVO.getOperationTime())));
            data.put("stopTime",sdf.format(new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).parse(appRobotAccountInfoGetVO.getAbateTime())));
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),data);
        } catch (Exception e) {
            throw new DataAccessException("【APP_机器人登录】登录失败",e);
        }
    }

    /**
     * <desc>
     *      机器人APP退出登录
     * </desc>
     *
     * @param token 登录token
     * @param robotUnique 机器人唯一码
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/10/15
     */
    @ResponseBody
    @PostMapping("logout")
    public MessageVO robotLogout(String token, String robotUnique, HttpServletRequest request){
        try {
            AppRobotLoginCacheVO appRobotLoginCacheVO = iAppUserInfoCacheServiceClient.getRobotLoginCache(token);
            if (appRobotLoginCacheVO != null) {
                String cacheKey = String.format("%s%s", RedisConstant.ROBOT_USER_REDIS_KEY, appRobotLoginCacheVO.getAppRobotAccountId());
                List<String> robotUniques = appRobotLoginCacheVO.getRobotUniques();
                if (robotUniques != null && robotUniques.size() > 0) {
                    boolean boo = robotUniques.remove(robotUnique);
                    if (robotUniques.size() > 0) {
                        appRobotLoginCacheVO.setRobotUniques(robotUniques);
                        redisService.set(cacheKey,RedisConstant.REDIS_ROBOT_USER_CACHE_TIME,appRobotLoginCacheVO);
                    } else {
                        redisService.del(cacheKey);
                    }
                    if (boo) {
                        // 保存退出登录日志
                        AppRobotOperateLogPO appRobotOperateLogPO = new AppRobotOperateLogPO();
                        Date nowTime = new Date();
                        appRobotOperateLogPO.setAppRobotOperateLogId(LogicIdUtil.bussinessId());
                        appRobotOperateLogPO.setAppRobotAccountId(appRobotLoginCacheVO.getAppRobotAccountId());
                        appRobotOperateLogPO.setAccount(appRobotLoginCacheVO.getAccount());
                        String city = request.getParameter("city");
                        appRobotOperateLogPO.setLocation(city);
                        String ip = HttpProtocolUtil.getIpAddr(request);
                        appRobotOperateLogPO.setIpAddress(ip);
                        appRobotOperateLogPO.setOperateType(2);
                        appRobotOperateLogPO.setStatus(DataStatusEnum.NORMAL.getType());
                        appRobotOperateLogPO.setCreateTime(nowTime);
                        appRobotOperateLogPO.setUpdateTime(nowTime);
                        iRobotLoginLogServiceClient.save(appRobotOperateLogPO);
                    }
                } else {
                    redisService.del(cacheKey);
                }
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【APP_机器人退出登录】退出登录失败",e);
        }
    }

//    public static void main(String[] args) throws Exception {
//        String token = UserTokenUtil.tokenEncrypt("123456","88BE65278OPP54123658BAC74166BE",SystemTypeEnum.ROBOT.getType());
//        System.out.println(token);
//        System.out.println(UserTokenUtil.tokenDecrypt(token,"88BE65278OPP54123658BAC74166BE"));
//        List<String> list = new ArrayList<>();
//        list.add("aaa");
//        list.add("bbb");
//        System.out.println(list);
//        System.out.println(list.remove("ddd"));
//        System.out.println(list);
//        List<String> list1 = new ArrayList<>();
//        System.out.println(list1);
//        System.out.println(list1.remove("ddd"));
//        System.out.println(list1);
//    }

    /**
     * <desc>
     *      获取项目列表
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate  2020/8/3
     */
    @ResponseBody
    @PostMapping("getProjectList")
    public Object getProjectList(String token, HttpServletRequest request){
        try {
            AppRobotLoginCacheVO appRobotLoginCacheVO = iAppUserInfoCacheServiceClient.getRobotLoginCache(token);
            if (appRobotLoginCacheVO == null || StringUtils.isBlank(appRobotLoginCacheVO.getAccount())){
                return new MessageVO(AppErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            List<AppRobotProjectInfoVO> projectInfoVOList = iAppRobotLoginServiceClient.getProjectIdList(appRobotLoginCacheVO.getDeveloperUserId());
            List<Map<String, Object>> resultList = new ArrayList<>();

            if (projectInfoVOList.isEmpty()){
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "无项目信息");
            }
            for (AppRobotProjectInfoVO appRobotProjectInfoVO : projectInfoVOList){
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("projectId", appRobotProjectInfoVO.getProjectId());
                resultMap.put("projectName", appRobotProjectInfoVO.getProjectName());
                resultList.add(resultMap);
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultList);
        }catch (Exception e){
            throw new DataAccessException("【APP_机器人获取项目列表】获取项目列表失败", e);
        }
    }

    /**
     * <desc>
     *      切换项目
     * </desc>
     *
     * @return
     * @Author Zhu.yj
     * @createDate  2020/8/4
     */
    @ResponseBody
    @PostMapping("changeProject")
    public Object changeProject(String token, String projectId, HttpServletRequest request){
        try{
            Map<String, Object> resultMap = new HashMap<>();
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppRobotLoginCacheVO appRobotLoginCacheVO = iAppUserInfoCacheServiceClient.getRobotLoginCache(token);
            if (appRobotLoginCacheVO == null || StringUtils.isBlank(appRobotLoginCacheVO.getAccount())){
                return new MessageVO(AppErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            AppRobotProjectInfoVO appRobotProjectInfoVO = iAppRobotLoginServiceClient.changeProject(projectId, appRobotLoginCacheVO.getDeveloperUserId());
            if (StringUtils.isBlank(appRobotProjectInfoVO.getProjectId())){
                return new MessageVO(AppErrorCodeEnum.USER_NOT_PROJECT.getErrorCode());
            }
            if (2 == appRobotProjectInfoVO.getStatus()){
                return new MessageVO(AppErrorCodeEnum.DEVELOPER_AUTH_PASSED.getErrorCode());
            }
            if (2 == appRobotProjectInfoVO.getProjectStatus()){
                return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_FORBIDDEN.getErrorCode());
            }
            resultMap.put("appId", appRobotLoginCacheVO.getDeveloperUserId());
            resultMap.put("appSecret", appRobotLoginCacheVO.getAppSecret());
            resultMap.put("projectId", projectId);
            resultMap.put("robotId", appRobotProjectInfoVO.getRobotId());
            resultMap.put("projectName", appRobotProjectInfoVO.getProjectName());
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
        }catch (Exception e){
            throw new DataAccessException("【APP_切换项目】切换项目失败", e);
        }
    }

}
